{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "In this notebook, you will implement the forward longitudinal vehicle model. The model accepts throttle inputs and steps through the longitudinal dynamic equations. Once implemented, you will be given a set of inputs that drives over a small road slope to test your model.\n",
    "\n",
    "The input to the model is a throttle percentage $x_\\theta \\in [0,1]$ which provides torque to the engine and subsequently accelerates the vehicle for forward motion. \n",
    "\n",
    "The dynamic equations consist of many stages to convert throttle inputs to wheel speed (engine -> torque converter -> transmission -> wheel). These stages are bundled together in a single inertia term $J_e$ which is used in the following combined engine dynamic equations.\n",
    "\n",
    "\\begin{align}\n",
    "    J_e \\dot{\\omega}_e &= T_e - (GR)(r_{eff} F_{load}) \\\\ m\\ddot{x} &= F_x - F_{load}\n",
    "\\end{align}\n",
    "\n",
    "Where $T_e$ is the engine torque, $GR$ is the gear ratio, $r_{eff}$ is the effective radius, $m$ is the vehicle mass, $x$ is the vehicle position, $F_x$ is the tire force, and $F_{load}$ is the total load force. \n",
    "\n",
    "The engine torque is computed from the throttle input and the engine angular velocity $\\omega_e$ using a simplified quadratic model. \n",
    "\n",
    "\\begin{align}\n",
    "    T_e = x_{\\theta}(a_0 + a_1 \\omega_e + a_2 \\omega_e^2)\n",
    "\\end{align}\n",
    "\n",
    "The load forces consist of aerodynamic drag $F_{aero}$, rolling friction $R_x$, and gravitational force $F_g$ from an incline at angle $\\alpha$. The aerodynamic drag is a quadratic model and the friction is a linear model.\n",
    "\n",
    "\\begin{align}\n",
    "    F_{load} &= F_{aero} + R_x + F_g \\\\\n",
    "    F_{aero} &= \\frac{1}{2} C_a \\rho A \\dot{x}^2 = c_a \\dot{x}^2\\\\\n",
    "    R_x &= N(\\hat{c}_{r,0} + \\hat{c}_{r,1}|\\dot{x}| + \\hat{c}_{r,2}\\dot{x}^2) \\approx c_{r,1} \\dot{x}\\\\\n",
    "    F_g &= mg\\sin{\\alpha}\n",
    "\\end{align}\n",
    "\n",
    "Note that the absolute value is ignored for friction since the model is used for only forward motion ($\\dot{x} \\ge 0$). \n",
    " \n",
    "The tire force is computed using the engine speed and wheel slip equations.\n",
    "\n",
    "\\begin{align}\n",
    "    \\omega_w &= (GR)\\omega_e \\\\\n",
    "    s &= \\frac{\\omega_w r_e - \\dot{x}}{\\dot{x}}\\\\\n",
    "    F_x &= \\left\\{\\begin{array}{lr}\n",
    "        cs, &  |s| < 1\\\\\n",
    "        F_{max}, & \\text{otherwise}\n",
    "        \\end{array}\\right\\} \n",
    "\\end{align}\n",
    "\n",
    "Where $\\omega_w$ is the wheel angular velocity and $s$ is the slip ratio. \n",
    "\n",
    "We setup the longitudinal model inside a Python class below. The vehicle begins with an initial velocity of 5 m/s and engine speed of 100 rad/s. All the relevant parameters are defined and like the bicycle model, a sampling time of 10ms is used for numerical integration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.image as mpimg\n",
    "\n",
    "class Vehicle():\n",
    "    def __init__(self):\n",
    " \n",
    "        # ==================================\n",
    "        #  Parameters\n",
    "        # ==================================\n",
    "    \n",
    "        #Throttle to engine torque\n",
    "        self.a_0 = 400\n",
    "        self.a_1 = 0.1\n",
    "        self.a_2 = -0.0002\n",
    "        \n",
    "        # Gear ratio, effective radius, mass + inertia\n",
    "        self.GR = 0.35\n",
    "        self.r_e = 0.3\n",
    "        self.J_e = 10\n",
    "        self.m = 2000\n",
    "        self.g = 9.81\n",
    "        \n",
    "        # Aerodynamic and friction coefficients\n",
    "        self.c_a = 1.36\n",
    "        self.c_r1 = 0.01\n",
    "        \n",
    "        # Tire force \n",
    "        self.c = 10000\n",
    "        self.F_max = 10000\n",
    "        \n",
    "        # State variables\n",
    "        self.x = 0\n",
    "        self.v = 5\n",
    "        self.a = 0\n",
    "        self.w_e = 100\n",
    "        self.w_e_dot = 0\n",
    "        \n",
    "        self.sample_time = 0.01\n",
    "        \n",
    "    def reset(self):\n",
    "        # reset state variables\n",
    "        self.x = 0\n",
    "        self.v = 5\n",
    "        self.a = 0\n",
    "        self.w_e = 100\n",
    "        self.w_e_dot = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Implement the combined engine dynamic equations along with the force equations in the cell below. The function $\\textit{step}$ takes the throttle $x_\\theta$ and incline angle $\\alpha$ as inputs and performs numerical integration over one timestep to update the state variables. Hint: Integrate to find the current position, velocity, and engine speed first, then propagate those values into the set of equations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Vehicle(Vehicle):\n",
    "    def step(self, throttle, alpha):\n",
    "        # ==================================\n",
    "        #  Implement vehicle model here\n",
    "        # ==================================\n",
    "        \n",
    "        self.v += self.sample_time * self.a\n",
    "        self.x += self.sample_time * self.v\n",
    "        self.w_e += self.sample_time * self.w_e_dot\n",
    "        \n",
    "        F_g = self.m * self.g * np.sin(alpha)\n",
    "        R_x = self.c_r1 * self.v\n",
    "        F_aero = self.c_a * (self.v ** 2)\n",
    "        F_load = F_aero + R_x + F_g\n",
    "        \n",
    "        w_w = self.GR * self.w_e\n",
    "        s = (w_w * self.r_e - self.v) / self.v\n",
    "        F_x = 0\n",
    "        if abs(s) < 1:\n",
    "            F_x = self.c * s\n",
    "        else:\n",
    "            F_x = self.F_max\n",
    "        accel = (F_x - F_load) / self.m\n",
    "        \n",
    "        T_e = throttle * (self.a_0 + self.a_1 * self.w_e + self.a_2 * (self.w_e ** 2))\n",
    "        \n",
    "        w_e_dot = (T_e - self.GR * self.r_e * F_load) / self.J_e\n",
    "        \n",
    "\n",
    "        self.a = accel\n",
    "        self.w_e_dot = w_e_dot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the model, you can send constant throttle inputs to the vehicle in the cell below. You will observe that the velocity converges to a fixed value based on the throttle input due to the aerodynamic drag and tire force limit. A similar velocity profile can be seen by setting a negative incline angle $\\alpha$. In this case, gravity accelerates the vehicle to a terminal velocity where it is balanced by the drag force."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sample_time = 0.01\n",
    "time_end = 100\n",
    "model = Vehicle()\n",
    "\n",
    "t_data = np.arange(0,time_end,sample_time)\n",
    "v_data = np.zeros_like(t_data)\n",
    "\n",
    "# throttle percentage between 0 and 1\n",
    "throttle = 0.2\n",
    "\n",
    "# incline angle (in radians)\n",
    "alpha = 0\n",
    "\n",
    "for i in range(t_data.shape[0]):\n",
    "    v_data[i] = model.v\n",
    "    model.step(throttle, alpha)\n",
    "    \n",
    "plt.plot(t_data, v_data)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will now drive the vehicle over a slope as shown in the diagram below.\n",
    "\n",
    "![ramp](ramp.png)\n",
    "\n",
    "To climb the slope, a trapezoidal throttle input is provided for the next 20 seconds as shown in the figure below. \n",
    "\n",
    "![throttle](throttle.png)\n",
    "\n",
    "The vehicle begins at 20% throttle and gradually increases to 50% throttle. This is maintained for 10 seconds as the vehicle climbs the steeper slope. Afterwards, the vehicle reduces the throttle to 0.\n",
    "\n",
    "In the cell below, implement the ramp angle profile $\\alpha (x)$ and throttle profile $x_\\theta (t)$ and step them through the vehicle dynamics. The vehicle position $x(t)$ is saved in the array $\\textit{x_data}$. This will be used to grade your solution.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD8CAYAAABn919SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3Xl8VNX9//HXyU4WCGRhh7DvshitoFVR9Iv71irWVrRY3JdWW7W2aFerdalb69dv3UUUUQutG1btz7oghrCEQGRLIIFsELInJJk5vz8yaIgJCcnM3JnJ+/l48JjJvXdyPzkzeXNy7r3nGmstIiIS/MKcLkBERLxDgS4iEiIU6CIiIUKBLiISIhToIiIhQoEuIhIiFOgiIiFCgS4iEiIU6CIiISLCnztLTk62aWlp/tyliEjQW7NmzV5rbUpH2/k10NPS0sjIyPDnLkVEgp4xZmdnttOQi4hIiFCgi4iECAW6iEiIUKCLiIQIBbqISIhQoIuIhAgFuohIiFCgi4j40N7qA9yzIpvK+kaf78uvFxaJiPQULrflpVU7eXDlV9Q2uDhhdDJzJvb36T4V6CIiXratpIrbXtvAuvxyjh+dxG/OncTo1ASf71eBLiLiJU0uN//331we/vcWYqPCeWTeNM6dOghjjF/2r0AXEfGCgv213LRkLZm7ypk7aQC/O38yKQnRfq1BgS4i0k3vZRfx89fW47b4vVfekgJdRKSLGprc3PvOZp79NI8pg/vw+A+mMzwpzrF6FOgiIl2wr/oA1y7OZHVuGVfMSuPOM8cTHRHuaE0dnodujHnGGFNijNnYxrrbjDHWGJPsm/JERAJPTlEl5z3xKevyy/nLJdO459xJjoc5dO7CoueAua0XGmOGAqcBu7xck4hIwHp/UzEX/fUzGprcLL16JudPH+x0SV/rMNCttR8DZW2sehj4BWC9XZSISCBa/MVOrn4xg1Gp8ay44QSmDU10uqRDdGkM3RhzLrDbWrveiSO5IiL+ZK3l0Q+28fC/tzB7XApPXDaD2KjAOwR5xBUZY2KBu4DTO7n9QmAhwLBhw450dyIijnK5LXev2MhLq3Zx4YzB3HfRUUSGB+Y0WF2pahQwAlhvjMkDhgCZxpgBbW1srX3KWpturU1PSenwptUiIgGjyeXm5lfW8tKqXVx94kge/P7UgA1z6EIP3VqbBaQe/NoT6unW2r1erEtExFGNnjB/O6uI2+eO59qTRzldUoc6c9riEuBzYJwxpsAYs8D3ZYmIOKfR5ebGl5vD/FdnTQiKMIdO9NCttZd2sD7Na9WIiDisocnNDS9nsnJTMb8+eyILThjhdEmdFniHaUVEHNLkcnPTkrWs3FTMPedM5IrjgyfMQXcsEhEBwO223PFGFu9mF7Ho7OALc1Cgi4hgreX3b21m2ZoCbpkzhh8H0TBLSwp0EenxHvtwG898msuVx6dx86ljnC6nyxToItKjvfB5Hg+9v4WLZgzh12dNdGQec29RoItIj7Uyu4i7V2QzZ0J/7rtoCmFhwRvmoEAXkR5qfX45N72ylqOGJPLYpdOJCOArQDsr+H8CEZEjlF9Wy4LnvyQlIZqn56fTK8r5ucy9Qeehi0iPUlHbyJXPfUmjy/LKFceSHO/fGzn7knroItJjNDS5ufqlDHbtq+WpHx3N6NR4p0vyKvXQRaTHuOef2azaUcZfLpnGd0YmOV2O16mHLiI9wkurdvLyF7u49uRRAXXbOG9SoItIyFudW8Y9K7KZPS6F204f53Q5PqNAF5GQtru8jmtfWsOwfrE8cul0woP8XPPDUaCLSMiqa3Cx8IUMGprcPHV5Or1jIp0uyad0UFREQpK1ljve2MCmwkqenp8ecme0tEU9dBEJSS+u2snydXv42ZyxnDK+v9Pl+IUCXURCzvr8cn73r03MHpfC9bNHO12O3yjQRSSklNc2cN3iTFITYnjo4mlBP+HWkdAYuoiEDLfbcuvS9ZRU1fPaNbPoGxfldEl+pR66iISMJz/ezgc5JfzqrIlMG5rodDl+p0AXkZCwasc+HnjvK846aiCXzxzudDmOUKCLSNDbV32Am5asJS05jvsuOiqo7zrUHQp0EQlq1lp+vmwD5XWNPH7pDOKje+6hQQW6iAS15z7L48OcEn55xngmDurtdDmOUqCLSNDatKeSe9/O4dTxqcyfleZ0OY5ToItIUKptaOLGJZkkxkZy//d67rh5Sz13sElEgtrv/rWJHXtreGnBd0gKodvIdYd66CISdN7OKmTJ6nyuPnEUx49OdrqcgKFAF5Ggsru8jjte38DUoYncevpYp8sJKAp0EQkabrflZ6+uw23h0XnTiAxXhLWk1hCRoPHMp7l8kVvG3edMZHhSnNPlBBwFuogEhS3FVdz/3lecNrE/3zt6iNPlBKQOA90Y84wxpsQYs7HFsj8bY3KMMRuMMW8aY3reLDgi4jcNTW5++uo6EqIjuPfCKTpFsR2d6aE/B8xttex9YLK19ihgC3Cnl+sSEfna4x9uJXtPJX+4YArJOkWxXR0GurX2Y6Cs1bKV1tomz5erAP39IyI+sXbXfp74z3YumjGEuZMHOF1OQPPGGPqPgXe88H1ERA5R1+Di1qXr6Z8Qzd3nTnS6nIDXrUA3xtwFNAGLD7PNQmNMhjEmo7S0tDu7E5Ee5r53c9ixt4YHvj+V3jGRTpcT8Loc6MaY+cDZwGXWWtvedtbap6y16dba9JSUlK7uTkR6mE+27uW5z/K48vg0Zulq0E7p0lwuxpi5wO3ASdbaWu+WJCI9XUVdIz9ftp5RKXHcPne80+UEjc6ctrgE+BwYZ4wpMMYsAB4HEoD3jTHrjDFP+rhOEelBfrMim5KqAzx08TRiIsOdLidodNhDt9Ze2sbip31Qi4gI72QV8sba3dx86him9sAbPXeHrhQVkYBRUlXPL9/MYsrgPtxwyminywk6CnQRCQjWWu58PYuaBhcPXzJVE291gVpMRALC0ox8Psgp4fa54xmdmuB0OUFJgS4ijssvq+W3/9zEcSP7caXuDdplCnQRcZTLbbl16XqMMTzw/amEhWnira5SoIuIo575JJfVec1znA/pG+t0OUFNgS4ijtlSXMWfV2qOc29RoIuII1rOcf7HCzTHuTd06dJ/EZHueswzx/mTPzyalATNce4N6qGLiN9l7trPEx9t0xznXqZAFxG/qm1o4tal6xnYp5fmOPcyDbmIiF/96Z0ccvfW8PJPvqM5zr1MPXQR8ZuPt5Tywuc7WXDCCGaN0hzn3qYeujjG7bbUNbqoaWjiQKMbgIO3SrFYDIaoiDBiIsOIiQwnOiJMZ0IEsYra5jnOR6fG8/P/Ged0OSFJgS5e19DkJn9/LXl7a8jbV0tRRR2lVQcorT7A3qoG9tU0UNvQRG2D64i/d3REGLFR4fTpFUmf2CgSe0WSGBtJoufr5PgoUhOiSe0dQ//eMaTERxMVoT9EA8GiFRvZV93A3y8/RnOc+4gCXbqltqGJdbvKydpdQdbuCjburmBXWS3uFjcljIkMIyUhmpT4aNKSY5kxPJH46AhioyKIiw6nV1REc+8bMMZwsA9uaf7Pob7RRX2Ti/pGNwcaXdQ2uKioa6S8rpHy2gby9tVQUddIRV0jbd0MMSkuipSEaAb0iWFI314M6RvL0L6xDOnbi6H9YukbG6mev4/9a8Melq/bw89OG8uUIX2cLidkKdClyzYUlLPwhTUUVdYDMDixF1MG9+GcqYNIS4ojLTmOEclxfgtMl9uyv7aB4sp6SioPND9WNT8WVx6gqLKOdfnllNc2HvK6uKhwhngCflhSLCOT4xiRHM+IlDgG9o7R3CLdtKe8jl++kcXUoYlcd/Iop8sJaQp06ZJ3sgq55dV1JMdH8/T8dKYP60u/uChHawoPMyTHR5McH82kQe1vV1XfSMH+Ogr215FfVtv8uL+W/LJaPt+x75ChoJjIMNKS4hiZ0vyf04jkeEamxDEyOY7EWGd/3mDgcltueXUdLrfl0XnTiNAc5z6lQJcj9vQnufz+rU1MH5rIU5enkxwfXFf5JcREMmFgJBMG9v7WOmstJVUH2FFaw4691eSW1pC7t4bNhVW8l12Mq8VYUnJ8NGP7xzO2fwJjDj6mxivoW3jio22szi3joYunMjwpzulyQp4CXTrN5bb8/q1NPPtpHnMnDeAv80LvBr7GGPp7DqjOHJV0yLpGl5v8slp2lNawvbSarSXVbC2uYmlG/iG9+pSE5qAfk5rA2P4Jzc/7J9CnV88653rNzjIe+WAr500bxAXTBztdTo+gQJdOqW90cfMra3kvu5gFJ4zgl2dOILyHjS1HhocxMiWekSnxzKH/18vdbsvu8jq2lVSzpbiKLcXVbC2p4tUv86lr/Cbo+/eOZvyA3owfmMAEz+OolPiQvNVaZX0jN7+yjkGJMfzu/Mk66OwnCnTp0L7qA1z1Qgbr8stZdPZEfnzCCKdLCihhYYah/WIZ2i+W2eNTv15+MOi3FFextaSaLUVVbC6q4rPte2l0NQ/dRIYbRqcmMGFAAhMGNof8+AG9g3qyKmstv3pzI4UV9bx2zUxdDepHCnQ5rLy9NVzx7GoKK+r522UzmDt5oNMlBY2WQX/qhG969I0uNztKa8gpqmRTYSU5hVV8un0vb6zd/fU2yfFRzQE/IOHrXv3o1HiiIwJ/iGvJ6nxWrN/DraeNZcawvk6X06Mo0KVdmbv2c9XzGVhrefknx3H0cP1yekNkeBjjBiQwbkAC5037Zmy5rKaBnMJKNhdVkVNYSU5RFc9/vpOGpuaraCPCDKNS4puHbAb2ZuLA3kwc1DugDkpnFVRwz4psvjsmmetmj3a6nB5HgS5tendjETe/spYBfWJ47spjGZGsMxR8rV9cFLNGJzNr9DdznDS53OTtaz7LZrMn5FfnlrF83Z6vt0lNiGbioG8CftKgPgzvF+v38+fLaxu4dvEakuOjeGTe9B53jCUQKNDlENZanv4klz+8vZmpQxJ5en46SQHUA+xpIsLDGJ2awOjUBM6Z+s3J9ftrGthc2Dxks2lP8+MnW/fS5DmtMjYq/JBe/MSBvRk3IMFnZyW5PTd6Lq6sZ+nVMx2/JqGnUqDL1xpdbhYt38iS1fnMnTSAhy+ZRq+owB+z7Yn6ttGbr290sa2k+uuA31RYyT/W7ubFVTsBCDMwKiX+kN78hIHeGbL563+28UFOCb85dxLTNW7uGAW6AM1/Ll+3OJPPtu/j+tmjuPW0cbrkPcjERIYzeXAfJg/+Zq4Uay0F++vI3vNNbz4jb/8hQzb9e0e36Mn3YeKg3kc0ZPPuxkIeWLmF86cN4vKZw73+c0nnKdCFHaXVLHg+g93763jo4qlcOEN3Xw8Vxnxzpk3LW721NWTz3y4M2WzcXcFPX13PtKGJ/Omio3S+ucOMbWt6Oh9JT0+3GRkZftufdOyzbXu5dnEm4WGG//3R0RyT1s/pksQh3xqy8TxWH2gCvj1kMzIlnkXLN2KAf9xwPKkJMc7+ACHMGLPGWpve0XbqofdgS1bv4tf/2MiI5Dienn8Mw5JinS5JHNTWkI3b3Txks6mw4uuA/7LFWTa9IsNZdu1MhXmAUKD3QI0uN394azPPfZbHSWNTeOwH03U1n7QpLMwwLCmWYUmxh1xUdnDIZnDfXpp0K4B0GOjGmGeAs4ESa+1kz7J+wKtAGpAHXGyt3e+7MsVb9lYf4LrFmazOLWPBCSO484zxmtJUjtjBs2wksHTmN/k5YG6rZXcAH1hrxwAfeL6WALehoJxzHvuE9fnl/OWSafz67IkKc5EQ0uFvs7X2Y6Cs1eLzgOc9z58HzvdyXeJly9YU8L0nPyfMGF6/dhbnazpTkZDT1TH0/tbaQgBrbaExJrWjF4gzGprc/PHt5vHyWaOSePwHM3QVn0iI8vlBUWPMQmAhwLBhw3y9O2khv6yWG5asZX1+OVedMII7NF4uEtK6GujFxpiBnt75QKCkvQ2ttU8BT0Hzeehd3J8coZXZRdz22nos8OQPNe2tSE/Q1e7aCmC+5/l8YLl3ypHuamhy87t/bWLhi2sYnhTHWzd+V2Eu0kN05rTFJcDJQLIxpgC4G/gTsNQYswDYBXzfl0VK5+zaV8tNr6xlXX45V8xK484zxwfFDRFExDs6DHRr7aXtrDrVy7VIF1lrWZqRz2//uYmwMMPfLpvBGVPUKxfpaXSlaJDbW32AO9/I4v1NxcwcmcSDF09lUGIvp8sSEQco0IPYvzcVc8cbG6isb+JXZ03gx8eP0JS3Ij2YAj0IVdQ28oe3N7E0o4AJA3uz+KppjBuQ4HRZIuIwBXqQeXdjIb9enk1ZTQPXnjyKW+aM0YFPEQEU6EGjpKqeu5dn887GIiYO7M2zVxxzyDSnIiIK9ABnrWXZmgJ+/9Zm6hpd/GLuOH7y3ZFE6opPEWlFgR7AcooqWbQ8m9W5ZRyb1o97L5rCqJR4p8sSkQClQA9AFXWNPPz+Fl5ctZPeMRH88YIpzDtmqM5gEZHDUqAHELfbsiyzgPveyWF/bQOXfWc4t54+lsRYzY4oIh1ToAeIDQXlLFqezbr8co4e3pfnzz1WBz1F5Igo0B1WVtPAn9/L4ZUv80mOj+ahi6dywfTBGKPhFRE5Mgp0h7jclpe/2MkDK7dQc6CJq04YwU2njiFBN2sWkS5SoDvgy7wy7l6ezabCSo4fncQ950xiTH9d6Ski3aNA96OSynrufSeHN9fuZlCfGP562QzOmDxAwysi4hUKdD9odLl57tM8HvlgKw1Nbm6YPZrrZo8iNkrNLyLeo0Txsc+27+Xu5dlsLanmlPGpLDp7ImnJcU6XJSIhSIHuI0UV9fzh7c38c/0ehvbrxd8vT2fOxP5OlyUiIUyB7mWNLjfPfprLI//eSqPbcsucMVxz0ihiIjUjooj4lgLdi77MK+PON7LYVlLNnAmpLDp7EsOSYp0uS0R6CAW6F1QfaOL+d3N44fOdDE7U8IqIOEOB3k0f5ZRw15tZFFbWc+Xxadx2+jjiotWsIuJ/Sp4uqqpv5J4Vm3g9s4AxqfEsu2YWRw/v63RZItKDKdC7YM3O/dzy6lp276/jxlNGc8Mpo3UbOBFxnAL9CDS53Dz+0TYe+3AbA/vEsPTqmaSn9XO6LBERQIHeafuqD3DjkrV8tn0fF04fzD3nTaK3JtISkQCiQO+EDQXlXPtSJqXVB7j/e0dxcfpQp0sSEfkWBXoH3lxbwO2vZ5ESH83r18xiyhDddEJEApMCvR3WWv76n+38+b2vOG5kP/562dH0i9Ot4EQkcCnQ29DkcrNoRTYvf7GL86cN4v7vTSUqIszpskREDkuB3kqjy80tr6zjraxCrjt5FD//n3Gar1xEgoICvYVGl5ublqzlnY1F3HXmBH5y4kinSxIR6TQFukejy82NL6/l3ewifnXWBK76rsJcRIKLAp3mA6B3vpHFu9lF/PrsiSw4YYTTJYmIHLFuHekzxvzUGJNtjNlojFlijInxVmH+9ODKLSxbU8BNp45RmItI0OpyoBtjBgM3AenW2slAODDPW4X5y8tf7OLxj7Yx75ih/HTOGKfLERHpsu6eixcB9DLGRACxwJ7ul+Q/X+aVsWj5Rk4am8Lvz5+ss1lEJKh1OdCttbuBB4BdQCFQYa1d6a3CfK2oop5rX8pkSN9ePHrpdCLCdZ65iAS37gy59AXOA0YAg4A4Y8wP29huoTEmwxiTUVpa2vVKvajJ5eb6lzOpbWjif3+UTp9emmRLRIJfd7qlc4Bca22ptbYReAOY1Xoja+1T1tp0a216SkpKN3bnPY9/tI01O/dz74VTGDcgwelyRES8ojuBvgs4zhgTa5oHn08FNnunLN/J3LWfxz7cxvnTBnHetMFOlyMi4jXdGUP/AlgGZAJZnu/1lJfq8onahiZ++uo6BvSO4bfnT3a6HBERr+rWhUXW2ruBu71Ui8898u+t7NxXyysLj9PNKUQk5PSYUzs2F1by909yuSR9KMeNTHK6HBERr+sRge52W+56M4s+vSK544zxTpcjIuITPSLQX88sIHNXOb88cwJ9dZMKEQlRIR/o9Y0uHly5halD+nDRDJ3VIiKhK+QD/ZlPcymqrOfOMyfo0n4RCWkhHehlNQ387aPtzJmQqgOhIhLyQjrQn/5kB9UNTfxirg6EikjoC9lAr6hr5IXPdnLG5AGM7a/L+0Uk9IVsoL/wWR5VB5q4fvZop0sREfGLkAz02oYmnvk0l1PGpzJpUB+nyxER8YuQDPTX1xSwv7aR62ePcroUERG/CblAt9by/Oc7OWpIH2YM6+t0OSIifhNygf759n1sK6nm8plpOu9cRHqUkAv05z/Po29sJGcfNdDpUkRE/CqkAr2oop73NxVzyTHDiIkMd7ocERG/CqlAf3PtbtwW5h0z1OlSRET8LmQC3VrL65kFHD28L2nJcU6XIyLidyET6Fm7K9hWUs1FM4Y4XYqIiCNCJtBfX1NAVEQYZ+lgqIj0UCER6E0uN//cUMhpE/vTp5fuFSoiPVNIBPrq3DLKaho4R71zEenBQiLQ380uIiYyjBPHpjhdioiIY4I+0N1uy7sbizhpbAqxURFOlyMi4pigD/S1+eWUVB3gjMkabhGRni3oA31ldhGR4YbZ41OdLkVExFFBH+j/+aqUY0f009ktItLjBXWgF1bU8VVxFSeO0cFQEZGgDvT/btkLwEnjFOgiIkEd6P9vSyn9e0czTjeBFhEJ3kBvcrn579ZSThyTohtZiIgQxIG+YXcFlfVNuphIRMQjaAP9ix1lAMwaleRwJSIigaFbgW6MSTTGLDPG5BhjNhtjZnqrsI6szt3HqJQ4kuKj/bVLEZGA1t0e+iPAu9ba8cBUYHP3S+qYy23JyNvPsSPUOxcROajLk58YY3oDJwJXAFhrG4AG75R1eDlFlVQdaOI7I/r5Y3ciIkGhOz30kUAp8KwxZq0x5u/GGL/c+211bvP4+bEKdBGRr3Un0COAGcDfrLXTgRrgjtYbGWMWGmMyjDEZpaWl3djdN1bnljE4sReDEnt55fuJiISC7gR6AVBgrf3C8/UymgP+ENbap6y16dba9JQU75xiuHZXOelpfb3yvUREQkWXA91aWwTkG2PGeRadCmzySlWHUVJZT1FlPUcNSfT1rkREgkp37whxI7DYGBMF7ACu7H5Jh7e+oAKAqUP6+HpXIiJBpVuBbq1dB6R7qZZO2VBQTniYYdIgBbqISEtBd6XohoIKxqTG0ysq3OlSREQCSlAFurWWDQXlTNX4uYjItwRVoBfsr2N/bSNTNH4uIvItQRXoG3c3HxA9SoEuIvItQRXoXxVXYQyM1Q0tRES+JagCfUtxFcP7xRITqQOiIiKtBVmgV6t3LiLSjqAJ9ANNLnL31jBugAJdRKQtQRPoO0prcLktY9RDFxFpU9AE+pbiKgDGKdBFRNoUVIEeEWYYkeyXKddFRIJO0AT6V0XVjEiOIyoiaEoWEfGroEnHrSVVjNUBURGRdgVFoNc1uNhVVsvYVAW6iEh7giLQt5VUYy2MGxDvdCkiIgErKAL90Q+3ArrkX0TkcLp7xyK/OHV8KkP7xpKWpDNcRETaExSBPu/YYU6XICIS8IJiyEVERDqmQBcRCREKdBGREKFAFxEJEQp0EZEQoUAXEQkRCnQRkRChQBcRCRHGWuu/nRlTCuzs4suTgb1eLMdbVNeRUV1HJlDrgsCtLRTrGm6tTeloI78GencYYzKstelO19Ga6joyquvIBGpdELi19eS6NOQiIhIiFOgiIiEimAL9KacLaIfqOjKq68gEal0QuLX12LqCZgxdREQOL5h66CIichgBF+jGmLnGmK+MMduMMXe0sd4YYx71rN9gjJnhh5qGGmM+MsZsNsZkG2NubmObk40xFcaYdZ5/i3xdl2e/ecaYLM8+M9pY70R7jWvRDuuMMZXGmFtabeOX9jLGPGOMKTHGbGyxrJ8x5n1jzFbPY992XnvYz6IP6vqzMSbH8z69aYxJbOe1h33PfVDXPcaY3S3eqzPbea3P2uswtb3aoq48Y8y6dl7rkzZrLxsc+4xZawPmHxAObAdGAlHAemBiq23OBN4BDHAc8IUf6hoIzPA8TwC2tFHXycC/HGizPCD5MOv93l5tvKdFNJ9H6/f2Ak4EZgAbWyy7H7jD8/wO4L6ufBZ9UNfpQITn+X1t1dWZ99wHdd0D3NaJ99ln7dVeba3WPwgs8mebtZcNTn3GAq2HfiywzVq7w1rbALwCnNdqm/OAF2yzVUCiMWagL4uy1hZaazM9z6uAzcBgX+7Ti/zeXq2cCmy31nb1grJusdZ+DJS1Wnwe8Lzn+fPA+W28tDOfRa/WZa1daa1t8ny5Chjirf11p65O8ml7dVSbMcYAFwNLvLnPTtTUXjY48hkLtEAfDOS3+LqAbwdnZ7bxGWNMGjAd+KKN1TONMeuNMe8YYyb5qSQLrDTGrDHGLGxjvaPtBcyj/V8yJ9oLoL+1thCafyGB1Da2cbrdfkzzX1Zt6eg994UbPENBz7QzfOB0e30XKLbWbm1nvc/brFU2OPIZC7RAN20sa30aTme28QljTDzwOnCLtbay1epMmocVpgKPAf/wR03A8dbaGcAZwPXGmBNbrXeyvaKAc4HX2ljtVHt1lpPtdhfQBCxuZ5OO3nNv+xswCpgGFNI8tNGaY+3lcSmH7537tM06yIZ2X9bGsm61WaAFegEwtMXXQ4A9XdjG64wxkTS/YYuttW+0Xm+trbTWVnuevw1EGmOSfV2XtXaP57EEeJPmP+NacqS9PM4AMq21xa1XONVeHsUHh508jyVtbOPU52w+cDZwmfUMtLbWiffcq6y1xdZal7XWDfxfO/tz7HNmjIkALgRebW8bX7ZZO9ngyGcs0AL9S2CMMWaEp3c3D1jRapsVwOWeszeOAyoO/mnjK57xuaeBzdbah9rZZoBnO4wxx9Lctvt8XFecMSbh4HOaD6ptbLWZ39urhXZ7TU60VwsrgPme5/OB5W1s05nPolcZY+YCtwPnWmtr29mmM++5t+tqeczlgnb25/f2amEOkGOtLWhrpS/b7DDZ4MxnzNtHfb1w1PhMmo8UbweZmUYXAAAAy0lEQVTu8iy7BrjG89wAT3jWZwHpfqjpBJr/FNoArPP8O7NVXTcA2TQfqV4FzPJDXSM9+1vv2XdAtJdnv7E0B3SfFsv83l40/4dSCDTS3CNaACQBHwBbPY/9PNsOAt4+3GfRx3Vto3lM9eBn7MnWdbX3nvu4rhc9n50NNAfOQH+3V3u1eZY/d/Bz1WJbv7TZYbLBkc+YrhQVEQkRgTbkIiIiXaRAFxEJEQp0EZEQoUAXEQkRCnQRkRChQBcRCREKdBGREKFAFxEJEf8fCj5n3G72+k4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "time_end = 20\n",
    "t_data = np.arange(0,time_end,sample_time)\n",
    "x_data = np.zeros_like(t_data)\n",
    "throttle_data = np.zeros_like(t_data)\n",
    "alpha_data = np.zeros_like(t_data)\n",
    "v_data = np.zeros_like(t_data)\n",
    "\n",
    "# reset the states\n",
    "model.reset()\n",
    "\n",
    "throttle_data[:500] = np.arange(0.2, 0.5, 0.3/500)\n",
    "throttle_data[500:1500] = 0.5\n",
    "throttle_data[1500:] = np.arange(0.5, 0.0, -0.5/500)\n",
    "\n",
    "alpha_data[:673] = np.arctan2(1, 20)\n",
    "alpha_data[673:1509] = np.arctan2(1, 10)\n",
    "alpha_data[1509:] = 0\n",
    "\n",
    "\n",
    "# ==================================\n",
    "#  Learner solution begins here\n",
    "# ==================================\n",
    "\n",
    "\n",
    "for i in range(t_data.shape[0]):\n",
    "    x_data[i] = model.x\n",
    "    v_data[i] = model.v\n",
    "\n",
    "    model.step(throttle_data[i], alpha_data[i])\n",
    "\n",
    "# ==================================\n",
    "#  Learner solution ends here\n",
    "# ==================================\n",
    "\n",
    "# Plot x vs t for visualization\n",
    "# plt.plot(t_data, x_data)\n",
    "plt.plot(t_data, v_data)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you have implemented the vehicle model and inputs correctly, you should see that the vehicle crosses the ramp at ~15s where the throttle input begins to decrease.\n",
    "\n",
    "The cell below will save the time and vehicle inputs as text file named $\\textit{xdata.txt}$. To locate the file, change the end of your web directory to $\\textit{/notebooks/Course_1_Module_4/xdata.txt}$\n",
    "\n",
    "Once you are there, you can download the file and submit to the Coursera grader to complete this assessment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.vstack([t_data, x_data]).T\n",
    "np.savetxt('xdata.txt', data, delimiter=', ')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Congratulations! You have now completed the assessment! Feel free to test the vehicle model with different inputs in the cell below, and see what trajectories they form. In the next module, you will see the longitudinal model being used for speed control. See you there!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'y_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-20-82755b6cbdbb>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     15\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'equal'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     17\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'y_data' is not defined"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sample_time = 0.01\n",
    "time_end = 30\n",
    "model.reset()\n",
    "\n",
    "t_data = np.arange(0,time_end,sample_time)\n",
    "x_data = np.zeros_like(t_data)\n",
    "\n",
    "# ==================================\n",
    "#  Test various inputs here\n",
    "# ==================================\n",
    "for i in range(t_data.shape[0]):\n",
    "\n",
    "    model.step(0,0)\n",
    "    \n",
    "plt.axis('equal')\n",
    "plt.plot(x_data, y_data)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
